[iOS 8] UIAlert, UIActionSheet から UIAlertController へ
UIAlert, UIActionSheetに取って代わるUIAlertController
iOS 8では新しいUIAlertControllerというクラスが追加されました。これは従来のUIAlert, UIActionSheetに取って代わるものです。UIAlert, UIActionSheetは今のところほとんど変更が無いようですが、わざわざ同じ機能の新しいクラスを追加したということはしかるべき変更が後に行われる可能性が強そうです。
今回のサンプルコードです。
ViewController.swift
import UIKit class ViewController: UIViewController { @IBAction func alertButtonDidTouchUpInside(sender: AnyObject) { // アラートのインスタンスを生成 let alert = UIAlertController( title: "Title", message: "Message", preferredStyle: .Alert) // Actionを追加 addActionsToAlertController(alert) // TextFieldを追加 alert.addTextFieldWithConfigurationHandler{ textField in // 必要な設定を行う textField.delegate = self } // アラートを表示 self.presentViewController(alert, animated: true, completion: { println("Alert displayed") }) } @IBAction func actionSheetButtonDidTouchUpInside(sender: AnyObject) { let actionSheet = UIAlertController( title: "Title", message: "Message", preferredStyle: .ActionSheet) addActionsToAlertController(actionSheet) // actionSheet.addTextFieldWithConfigurationHandler{ textField in // // } // ActionSheetにTextFieldを追加することはできない追加して表示しようとするとランタイムエラー self.presentViewController(actionSheet, animated: true, completion: { println("ActionSheet displayed") }) } // AlertControllerにActionを追加 func addActionsToAlertController(controller: UIAlertController) { // 基本的にはActionが追加された順序でボタンが配置される // Cancelは例外的に一番下に配置される controller.addAction( UIAlertAction( title: "Cancel", style: .Cancel, handler: { action in println(action.title) })) controller.addAction( UIAlertAction( title: "Default", style: .Default, handler: { action in println(action.title) })) // 削除等のアクションを示す為に赤くなる controller.addAction( UIAlertAction( title: "Destructive", style: .Destructive, handler: { action in println(action.title) })) } } // UITextFieldDelegateを扱うためのエクステンション extension ViewController : UITextFieldDelegate { func textFieldDidEndEditing(textField: UITextField!) { println(textField.text) } }
生成方法
インスタンスの生成とボタンの追加はUIAlertViewではひとつにまとまった指定イニシャライザがありましたが、UIAlertControllerでは生成とボタンの追加のメソッドは分かれています。さらにボタンの追加はUIAlertActionインスタンスの追加によってなされ、UIAlertActionはボタンが押された時のハンドラを生成時に指定することが可能です。従来ではUIAlertView-BlocksなどのOSSを使わない場合はデリゲードとタグを用いたハンドリングが通例でしたが、ボタン、アラートごとにタグ用の定数を切る手間がなくなります。
インスタンス生成
l6 - l11
// アラートのインスタンスを生成 let alert = UIAlertController( title: "Title", message: "Message", preferredStyle: .Alert)
アラートのタイトルとメッセージが指定できるのは従来のAPI通りです。preferredStyleの後にUIAlertControllerStyleの値を入れて従来のUIAlertView風の表示スタイルかUIActionSheet風の表示スタイルを選択します。
UIAlertControllerStyle
enum UIAlertControllerStyle : Int { case ActionSheet // UIActionSheet風のアラート case Alert // UIAlertView風のアラート }
ボタン追加
l45 - l71
UIAlertActionをUIAlertControllerに追加することでボタンの追加と、ボタンをおした時の挙動を追加できます。
// AlertControllerにActionを追加 func addActionsToAlertController(controller: UIAlertController) { // 基本的にはActionが追加された順序でボタンが配置される // Cancelは例外的に一番下に配置される controller.addAction( UIAlertAction( title: "Cancel", style: .Cancel, handler: { action in println(action.title) })) controller.addAction( UIAlertAction( title: "Default", style: .Default, handler: { action in println(action.title) })) // 削除等のアクションを示す為に赤くなる controller.addAction( UIAlertAction( title: "Destructive", style: .Destructive, handler: { action in println(action.title) })) }
UIAlertAction生成時にはボタンのタイトルとスタイルとボタンを押した時の挙動を記述します
l56 - l62
UIAlertAction( title: "Default", style: .Default, handler: { action in println(action.title) }))
styleの後にUIAlertActionStyleを次の3つから選択することができます。
enum UIAlertActionStyle : Int { case Default // 通常のボタンタイトル表示スタイル case Cancel // キャンセルボタン表示スタイル、追加順序に関係なく最後にボタンが移動する case Destructive // 削除等の動作を明示的にするための赤いボタンタイトル表示スタイル }
表示方法
UIActionControllerはUIViewControllerのサブクラスとして定義されているため、従来通りのモーダルの表示方法で表示がなされます。
l19 - l24
// アラートを表示 self.presentViewController(alert, animated: true, completion: { println("Alert displayed") })
TextFieldの追加
UIAlertControllerStyle.Alertでスタイル指定されたUIAlertControllerに対してはUITextFieldを追加できます。
l14 - l18
// TextFieldを追加 alert.addTextFieldWithConfigurationHandler{ textField in // 必要な設定を行う textField.delegate = self }
メソッドの末尾クロージャではUITextFieldの追加の際に必要な設定を行うことができます。
尚、個々ではUIAlertContollerのインスタンスがプロパティで保持されないため、循環参照の危険性がありません。このためselfに対してweakやunownedの識別子を特に使っていません。
実際に動かす
改めて確認するまでもないですが、実際に動かしてみます。
参考サイト
iOS8でのダイアログ表示:廃止になるUIAlertViewと推奨されているUIAlertControllerのメリット - Qiita